home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 1.iso / dist / fw_exmh.idb / usr / freeware / lib / exmh-2.5 / aliases.tcl.z / aliases.tcl
Text File  |  2002-07-08  |  18KB  |  668 lines

  1. # aliases.tcl
  2. # Original contributed by Scott Stanton, sstanton@eng.sun.com
  3. # Tweaked for exmh integration by Brent Welch
  4. #
  5.  
  6. #
  7. # Aliases_Pref:
  8. #
  9. # This procedure displays a dialog box for editing the MH aliases
  10. # file.  
  11. #
  12. proc Aliases_Pref { {nalias {}} } {
  13.     global mhProfile
  14.     if ![info exists mhProfile(aliasfile)] {
  15.     if {![AliasesInitProfile]} {
  16.         return
  17.     }
  18.     }
  19.     set filename [Mh_Pathname $mhProfile(aliasfile)]
  20.     if ![file exists $filename] {
  21.     if [catch {open $filename w} it] {
  22.         Exmh_Status "Cannot create $filename\n$it"
  23.         return
  24.     }
  25.     close $it
  26.     }
  27.     if [Exwin_Toplevel .aliaspref "Alias Browser" Alias] {
  28.     .aliaspref.but.quit config -command {AliasesDismiss}
  29.     wm protocol .aliaspref WM_DELETE_WINDOW AliasesDismiss
  30.     Widget_AddBut .aliaspref.but save "Save" \
  31.         {Aliases_Save; Exwin_Dismiss .aliaspref}
  32.     Widget_AddBut .aliaspref.but import "Import" \
  33.         {Aliases_Import}
  34.     Widget_AddBut .aliaspref.but help "Help" \
  35.         {Aliases_Help}
  36.     Widget_Label .aliaspref.but label {left fill} \
  37.         -text "MH Alias Definitions"
  38.     frame .aliaspref.alias
  39.     frame .aliaspref.addr
  40.     pack .aliaspref.alias .aliaspref.addr -side left -fill both \
  41.         -padx 5 -pady 5
  42.     pack .aliaspref.addr -expand 1 
  43.     Widget_ListEditor .aliaspref.alias Aliases alias \
  44.         Aliases_Insert Aliases_Change Aliases_Delete Address_Rebuild
  45.     Widget_ListEditor .aliaspref.addr Addresses address \
  46.         Address_Insert Address_Change Address_Delete
  47.  
  48.     # Asymetric, but users can paste out of the Alias list,
  49.     # and paste into the Address entry.
  50.     .aliaspref.addr.listbox config -exportselection 0
  51.     
  52.     # Create search bindings in the entries.
  53.     bindtags .aliaspref.alias.entry \
  54.         [list .aliaspref.alias.entry Entry SearchAlias]
  55.     bind SearchAlias <KeyPress> \
  56.         {Widget_ListSearch .aliaspref.alias}
  57.     bind .aliaspref.alias.entry <space> {
  58.         set alias [AliasesComplete .aliaspref.alias]
  59.         Aliases_Insert
  60.         break
  61.     }
  62.     bind .aliaspref.alias.entry <Control-c> \
  63.         {Aliases_Delete ; break}
  64.     
  65.     bindtags .aliaspref.addr.entry \
  66.         [list .aliaspref.addr.entry Entry SearchAddress]
  67.     bind SearchAddress <KeyPress> \
  68.         {Widget_ListSearch .aliaspref.addr}
  69.     bind .aliaspref.addr.entry <Control-space> {
  70.         set address [AliasesComplete .aliaspref.addr]
  71.         break
  72.     }
  73.     foreach e {.aliaspref.alias.entry .aliaspref.addr.entry} {
  74.         Exmh_Debug bindtags $e [bindtags $e]
  75.     }
  76.     wm minsize .aliaspref 1 1
  77.  
  78.     }
  79.     focus .aliaspref.alias.entry
  80.     # The following command foils a spontaneous <Destroy> event
  81.     # that otherwise kills the dialog in the special case that we
  82.     # just created/destroyed the .aliasfile toplevel
  83.     Visibility_Wait .aliaspref
  84.     Aliases_Load
  85.     Aliases_Rebuild $nalias
  86. }
  87. proc AliasesComplete { parent } {
  88.     # Fetch the selected entry from the aliases listbox, if any
  89.     Exmh_Status AliasesComplete
  90.     set i [$parent.listbox curselection]
  91.     if {$i != {}} {
  92.     return [$parent.listbox get [lindex $i 0]]
  93.     } else {
  94.     return [$parent.entry get]
  95.     }
  96. }
  97. proc Aliases_Help {} {
  98.     Help Aliases "Tips for the Aliases interface"
  99. }
  100.  
  101. #
  102. # AliasesInitProfile
  103. #
  104. # Create the MH profile entry that names the alias file.
  105. #
  106. proc AliasesInitProfile {} {
  107.     global mhProfile aliasOK
  108.     if [winfo exists .aliasfile] {
  109.     return
  110.     }
  111.     Widget_Toplevel .aliasfile "Setup Alias File"
  112.     Widget_Message .aliasfile msg -aspect 1000 -text "
  113. The MH aliases are kept in a file (you choose the name)
  114. and this file is named in the AliasFile profile entry.
  115.  
  116. Should Exmh set that up for you now?"
  117.  
  118.     Widget_Frame .aliasfile rim Pad {top expand fill}
  119.     .aliasfile.rim configure -bd 10
  120.  
  121.     Widget_Label .aliasfile.rim l {left} -text "Alias file name: "
  122.     Widget_Entry .aliasfile.rim e {left fill}  -width 30
  123.     .aliasfile.rim.e insert 0 [glob ~]/.mh_aliases
  124.  
  125.     set aliasOK 0
  126.     Widget_Frame .aliasfile.rim but Menubar {top fill}
  127.     Widget_AddBut .aliasfile.rim.but yes "Yes" [list AliasesSetupCommit .aliasfile .aliasfile.rim.e]
  128.     Widget_AddBut .aliasfile.rim.but no "No" {destroy .aliasfile}
  129.     tkwait window .aliasfile
  130.     return $aliasOK
  131. }
  132.  
  133. proc AliasesSetupCommit {top entry} {
  134.     global mhProfile aliasOK
  135.  
  136.     set filename [$entry get]
  137.     regsub -all "\[ \t\n\]" $filename {} filename
  138.  
  139.     if ![file exists $filename] {
  140.     if [catch {open $filename w} it] {
  141.         .aliasfile.msg config -text "Cannot create $filename\n$it"
  142.         return
  143.     }
  144.     close $it
  145.     }
  146.     set mhProfile(aliasfile) $filename
  147.     if [catch {open ~/.mh_profile a} out] {
  148.     Exmh_Status "Cannot open ~/.mh_profile: $out" purple
  149.     unset mhProfile(aliasfile)
  150.     destroy .aliasfile
  151.     return
  152.     }
  153.     puts $out "AliasFile: $filename"
  154.     Exmh_Status "AliasFile: $filename"
  155.     close $out
  156.  
  157.     set aliasOK 1
  158.     destroy $top
  159. }
  160.  
  161. #
  162. # Aliases_Rebuild:
  163. #
  164. # Load the aliases list into the alias listbox.  If item is specified,
  165. # then that element of the list will be selected, otherwise no element
  166. # will be selected.
  167. #
  168. proc Aliases_Rebuild {{item {}}} {
  169.     global aliases alias
  170.     set top [.aliaspref.alias.listbox nearest 0]
  171.     .aliaspref.alias.listbox delete 0 end
  172.     set names [AliasesList]
  173.     eval .aliaspref.alias.listbox insert end $names
  174.     if {$item == {}} {
  175.     .aliaspref.alias.listbox selection clear 0 end
  176.     .aliaspref.alias.listbox see $top
  177.     set alias {}
  178.     } else {
  179.     set index [lsearch -exact $names $item]
  180.     .aliaspref.alias.listbox select set $index
  181.     .aliaspref.alias.listbox see $index
  182.     set alias $item
  183.     }
  184.     Address_Rebuild
  185. }
  186. proc AliasesList {} {
  187.     global aliasesOrder
  188.     set res {}
  189.     foreach a $aliasesOrder {
  190.     if [regexp {^[     ]*[;#]} $a] {
  191.         continue
  192.     }
  193.     if [regexp {^[     ]*$} $a] {
  194.         continue
  195.     }
  196.     if [regexp {^[     ]*<} $a] {
  197.         continue
  198.     }
  199.     lappend res $a
  200.     }
  201.     return $res
  202. }
  203. #
  204. # Address_Rebuild:
  205. #
  206. # Display addresses from currently selected alias in the address listbox.
  207. # If item is specified, then that element of the list will be selected,
  208. # otherwise no element will be selected.
  209. #
  210. proc Address_Rebuild {{item {}}} {
  211.     global aliases address alias
  212.  
  213.     # rebuild the address list based on the current alias selected
  214.     if {([string length $alias] > 0) && [info exists aliases($alias)]} {
  215.     .aliaspref.addr.listbox delete 0 end
  216.     set names [lsort $aliases($alias)]
  217.     eval .aliaspref.addr.listbox insert end $names
  218.     } else {
  219.     .aliaspref.addr.listbox delete 0 end
  220.     set item {}
  221.     }
  222.  
  223.     # now select appropriate item from the list
  224.     if {$item == {}} {
  225.     .aliaspref.addr.listbox selection clear 0 end
  226.     } else {
  227.     set index [lsearch -exact $names $item]
  228.     .aliaspref.addr.listbox select set $index
  229.     .aliaspref.addr.listbox see $index
  230.     set address [.aliaspref.addr.listbox get $index]
  231.     }
  232. }
  233. #
  234. # Aliases_New:
  235. #
  236. #    Create a new alias. For use with message display window (maybe...)
  237. #    Instead, what currently happens is that MsgShowInText side-effects
  238. #    our address variable so the Aliases_Pref UI is updated.
  239. #
  240. proc Aliases_New { nalias naddress } {
  241.     global aliases alias address
  242.     if [info exists aliases($nalias)] {
  243.     # Existing alias - invoke user interface
  244.     Aliases_Pref $nalias
  245.     set address $naddress
  246.     set alias $nalias
  247.     } else {
  248.     AliasesDirty
  249.     set aliases($alias) $naddress
  250.     catch {Aliases_Rebuild $alias}
  251.     }
  252. }
  253.  
  254. #
  255. # Aliases_Insert:
  256. #
  257. # Add the specified entry to the alias list, if it is unique.
  258. #
  259. proc Aliases_Insert {} {
  260.     global aliases alias address aliasesOrder
  261.     if ![info exist aliases($alias)] {
  262.     AliasesDirty
  263.     lappend aliases($alias) $address
  264.     lappend aliasesOrder $alias
  265.     } else {
  266.     # error, alias already exists
  267.     }
  268.     Aliases_Rebuild $alias
  269. }
  270.  
  271. #
  272. # Aliases_Change:
  273. #
  274. # Change the name of specified alias.  If the new name is already taken,
  275. # nothing changes.
  276. #
  277. proc Aliases_Change {} {
  278.     global aliases alias aliasesOrder
  279.     set current [.aliaspref.alias.listbox curselection]
  280.     if {[llength $current] == 1} {
  281.     set item [.aliaspref.alias.listbox get $current]
  282.     if {![info exists aliases($alias)]} {
  283.         set aliases($alias) $aliases($item)
  284.         unset aliases($item)
  285.         set ix [lsearch $aliasesOrder $item]
  286.         set aliasesOrder [lreplace $aliasesOrder $ix $ix $alias]
  287.         AliasesDirty
  288.         Aliases_Rebuild $alias
  289.     }
  290.     }
  291. }
  292.  
  293. #
  294. # Aliases_Delete:
  295. #
  296. # Delete the current selection from the list of aliases
  297. #
  298. proc Aliases_Delete {} {
  299.     global aliases alias aliasesOrder
  300.     if {[string length $alias] > 0} {
  301.     set ix [lsearch $aliasesOrder $alias]
  302.     if {$ix >= 0} {
  303.         AliasesDirty
  304.         set aliasesOrder [lreplace $aliasesOrder $ix $ix]
  305.         catch {unset aliases($alias)}
  306.         Aliases_Rebuild
  307.     }
  308.     }
  309. }
  310.  
  311.  
  312. #
  313. # Address_Insert:
  314. #
  315. # Add the specified entry to the address list.  Duplicates are allowed.
  316. #
  317. proc Address_Insert {} {
  318.     global aliases address alias
  319.     if {[string length $alias] > 0} {
  320.     set exists [info exists aliases($alias)]
  321.     AliasesDirty
  322.     lappend aliases($alias) $address
  323.     if {! $exists} {
  324.         Aliases_Rebuild $alias
  325.     }
  326.     Address_Rebuild $address
  327.     }
  328. }
  329.  
  330. #
  331. # Address_Change:
  332. #
  333. # Change the current address.
  334. #
  335. proc Address_Change {} {
  336.     global aliases address alias
  337.     set current [.aliaspref.addr.listbox curselection]
  338.     if {([llength $current] == 1) &&
  339.     ([string length $alias] > 0) && ([string length $address] > 0)} {
  340.     set oldaddr [.aliaspref.addr.listbox get $current]
  341.     if ![info exists aliases($alias)] {
  342.         AliasesDirty
  343.         set aliases($alias) $address
  344.         Aliases_Rebuild $alias
  345.         Address_Rebuild $address
  346.     } else {
  347.         set pos [lsearch $aliases($alias) $oldaddr]
  348.         if {$pos >= 0} {
  349.         AliasesDirty
  350.         set aliases($alias) \
  351.             [lreplace $aliases($alias) $pos $pos $address]
  352.         Address_Rebuild $address
  353.         }
  354.     }
  355.     }
  356. }
  357.  
  358. #
  359. # Address_Delete:
  360. #
  361. # Delete the current selection from the list of addresses
  362. #
  363. proc Address_Delete {} {
  364.     global aliases alias address
  365.     if {([string length $address] > 0) && 
  366.     ([string length $alias] > 0) &&
  367.     [info exists aliases($alias)]} {
  368.     set pos [lsearch $aliases($alias) $address]
  369.     if {$pos >= 0} {
  370.         set aliases($alias) \
  371.         [lreplace $aliases($alias) $pos $pos]
  372.         AliasesDirty
  373.         Address_Rebuild
  374.     }
  375.     }
  376. }
  377. #
  378. # AliasesDismiss:
  379. #
  380. # See if the database has been modified before quiting.
  381. #
  382. proc AliasesDirty {} {
  383.     global aliasesDirty
  384.     set aliasesDirty 1
  385. }
  386. proc AliasesIsDirty {} {
  387.     global aliasesDirty
  388.     if ![info exists aliasesDirty] {
  389.     return 0
  390.     } else {
  391.     return $aliasesDirty
  392.     }
  393. }
  394. proc AliasesClean {} {
  395.     global aliasesDirty
  396.     set aliasesDirty 0
  397. }
  398. proc AliasesIsClean {} {
  399.     global aliasesDirty
  400.     return [expr ! $aliasesDirty]
  401. }
  402.  
  403. proc AliasesDismiss {} {
  404.     set ok 0
  405.     if [AliasesIsDirty] {
  406.     if [AliasesDirtyDialog] {
  407.         set ok 1
  408.     }
  409.     } else {
  410.     set ok 1
  411.     }
  412.     if {$ok} {
  413.     catch {destroy .aliashelp}
  414.     Exwin_Dismiss .aliaspref
  415.     }
  416. }
  417. proc AliasesDirtyDialog {} {
  418.     if [catch {frame .aliaspref.dirty -bd 4 -relief ridge} t] {
  419.     Aliases_Save
  420.     destroy .aliaspref.dirty
  421.     return 1
  422.     }
  423.     message $t.msg -aspect 1000 -text "Save changes to aliases?"
  424.     pack $t.msg -padx 20 -pady 20
  425.     FontWidget button $t.yes -text OK -command {
  426.     Aliases_Save
  427.     destroy .aliaspref.dirty
  428.     }
  429.     FontWidget button $t.no -text Cancel -command {
  430.     destroy .aliaspref.dirty
  431.     }
  432.     FontWidget button $t.reset -text Reset -command {
  433.     Aliases_Load
  434.     Aliases_Rebuild
  435.     Exmh_Status "Reset aliases"
  436.     destroy .aliaspref.dirty
  437.     }
  438.     pack $t.yes $t.no $t.reset -padx 20 -side right
  439.     Widget_PlaceDialog .aliaspref .aliaspref.dirty
  440.     tkwait window .aliaspref.dirty
  441.     return [AliasesIsClean]
  442. }
  443. proc Aliases_CheckPoint {} {
  444.     if [AliasesIsDirty] {
  445.     Aliases_Save
  446.     }
  447. }
  448. #
  449. # Aliases_Load:
  450. #
  451. # This procedure attempts to load the MH alias file indicated in the
  452. # MH profile, creating it if necessary.  The contents of the alias
  453. # file will be stored in the global aliases array.
  454. #
  455. proc Aliases_Load {} {
  456.     global aliases mhProfile aliasesOrder aliases_sep
  457.  
  458.     AliasesClean
  459.     catch {unset aliases} ; set aliases(foo) foo ; unset aliases(foo)
  460.     set aliasesOrder {}
  461.     if ![info exists mhProfile(aliasfile)] {
  462.     return
  463.     }
  464.     if [catch {open [Mh_Pathname $mhProfile(aliasfile)]} input] {
  465.     Exmh_Status "Cannot open [Mh_Pathname $mhProfile(aliasfile)]: $input"
  466.     return
  467.     }
  468.     # clear the old aliases array and load the new one
  469.     set continue 0
  470.     while {[gets $input line] >= 0} {
  471.     set cont $continue
  472.     if [regexp {\\$} $line] {
  473.         set continue 1
  474.         set line [string trimright $line \\]
  475.     } else {
  476.         set continue 0
  477.     }
  478.     if {$cont} {
  479. #        append aliases($key) $line
  480.         regsub -all {[     ]*,[     ]*} $line , value
  481.         set aliases($key) \
  482.         [concat $aliases($key) [split [string trim $value "\t ,"] ,]]
  483.     } else {
  484.         if [regexp {^[     ]*[;#:]} $line] {
  485.         lappend aliasesOrder $line
  486.         } elseif [regexp "^\[ \t\]*$" $line] {
  487.         lappend aliasesOrder $line
  488.         } elseif [regexp "^\[ \t\]*<" $line] {
  489.         lappend aliasesOrder $line
  490.         } else {
  491.             regexp {([^;:]+)([:;])(.*)} $line match key sep other
  492.         lappend aliasesOrder [string trim $key]
  493. #        set aliases($key) $other
  494.         regsub -all {[     ]*,[     ]*} $other , value
  495.         set aliases($key) [split [string trim $value "\t ,"] ,]
  496.         set aliases_sep($key) $sep
  497.  
  498.         }
  499.     }
  500.     }
  501. #   foreach key [array names aliases] {
  502. #    set aliases($key) [AliasesChop $aliases($key)]
  503. #   }
  504.     close $input
  505. }
  506. proc AliasesChop { rawline } {
  507.     # Doomed to failure.
  508.     set list {}
  509.     Exmh_Debug AliasesChop $rawline
  510.     while {[string length $rawline] > 0} {
  511.     if [regexp -indices {^[     ]*("[^"]+"[     ]*<[^>]+>)[     ]*,?} \
  512.         $rawline match addr] {
  513.         Exmh_Debug [eval {string range $rawline} $addr]
  514.         lappend list [eval {string range $rawline} $addr]
  515.         set next [expr [lindex $match 1]+1]
  516.         set rawline [string range $rawline $next end]
  517.     } elseif [regexp -indices {^[     ]*(\([^\)]+\)[     ]*<[^>]+>)[     ]*,?}\
  518.         $rawline match addr] {
  519.         Exmh_Debug [eval {string range $rawline} $addr]
  520.         lappend list [eval {string range $rawline} $addr]
  521.         set next [expr [lindex $match 1]+1]
  522.         set rawline [string range $rawline $next end]
  523.     } elseif [regexp -indices {^[     ]*(<[^>]+>)[     ]*,?}\
  524.         $rawline match addr] {
  525.         Exmh_Debug [eval {string range $rawline} $addr]
  526.         lappend list [eval {string range $rawline} $addr]
  527.         set next [expr [lindex $match 1]+1]
  528.         set rawline [string range $rawline $next end]
  529.     } elseif [regexp -indices {^[     ]*([^     ]+)[     ]*,?}\
  530.         $rawline match addr] {
  531.         Exmh_Debug [eval {string range $rawline} $addr]
  532.         lappend list [eval {string range $rawline} $addr]
  533.         set next [expr [lindex $match 1]+1]
  534.         set rawline [string range $rawline $next end]
  535.     } else {
  536.         Exmh_Debug "miss"
  537.         break
  538.     }
  539.     }
  540. }
  541. #
  542. # Aliases_Save:
  543. #
  544. # This procedure writes the contents of the aliases array to the MH
  545. # alias file indicated in the MH profile.
  546. #
  547. proc Aliases_Save {} {
  548.     global aliases mhProfile aliasesOrder aliases_sep
  549.  
  550.     if [info exists aliases] {
  551.     if [catch {open [Mh_Pathname $mhProfile(aliasfile)] w} output] {
  552.         puts stderr "Cannot write [Mh_Pathname $mhProfile(aliasfile)]: $output"
  553.         return
  554.     }
  555.  
  556.     foreach alias $aliasesOrder {
  557.         if [regexp {^[     ]*[;#]} $alias] {
  558.         puts $output $alias
  559.         } elseif [regexp {^[     ]*$} $alias] {
  560.         puts $output $alias
  561.         } elseif [regexp {^[     ]*<} $alias] {
  562.         puts $output $alias
  563.         } elseif [info exists aliases($alias)] {
  564.         if [catch {set aliases_sep($alias)} sep] {
  565.             set sep :
  566.         }
  567.         puts -nonewline $output "$alias$sep "
  568.         set col [string length "$alias: "]
  569.         set first 1
  570.         foreach a $aliases($alias) {
  571.             if {! $first} {
  572.             puts -nonewline $output ", "
  573.             incr col 2
  574.             } else {
  575.             set first 0
  576.             }
  577.             set l [string length $a]
  578.             if {($col + $l > 77)} {
  579.             puts $output \\
  580.             puts -nonewline $output \t
  581.             set col 8
  582.             }
  583.             puts -nonewline $output $a
  584.             incr col $l
  585.         }
  586.         puts $output ""
  587.         }
  588.     }
  589.     close $output
  590.     AliasesClean
  591.     Exmh_Status "Saved aliases"
  592.     }
  593. }
  594. proc Aliases_Import {} {
  595.     global  mhProfile
  596.     if [AliasesIsDirty] {
  597.     if ![AliasesDirtyDialog] {
  598.         return
  599.     }
  600.     }
  601.     if ![info exists mhProfile(aliasfile)] {
  602.     if ![AliasesInitProfile] {
  603.         return
  604.     }
  605.     }
  606.     set f [frame .aliaspref.import -bd 4 -relief ridge]
  607.     Widget_Message $f msg -aspect 1000 -text "
  608. Exmh knows how to import aliases from .mailrc-like files.
  609. The format it expects is
  610. alias Foo Bar@xyz
  611. Enter the file name and hit OK"
  612.     Widget_Frame $f rim Pad {top expand fill}
  613.     $f.rim configure -bd 10
  614.  
  615.     Widget_Label $f.rim l {left} -text "mailrc file name: "
  616.     Widget_Entry $f.rim e {left fill} -width 30
  617.     $f.rim.e insert 0 [glob ~]/.mailrc
  618.  
  619.     set aliasOK 0
  620.     Widget_Frame $f.rim but Menubar {top fill}
  621.     Widget_AddBut $f.rim.but yes "OK" [list AliasesImportOK $f.rim.e $f]
  622.     Widget_AddBut $f.rim.but no "Cancel" [list destroy $f]
  623.     Widget_PlaceDialog .aliaspref $f 
  624.     tkwait window $f
  625. }
  626.  
  627. proc AliasesImportOK { entry dialog } {
  628.     if [Aliases_ImportFile [$entry get]] {
  629.     Aliases_Load
  630.     Aliases_Rebuild
  631.     destroy $dialog
  632.     } else {
  633.     lower $dialog
  634.     update idletasks
  635.     raise $dialog
  636.     }
  637. }
  638. proc Aliases_ImportFile { f } {
  639.     global mhProfile aliases
  640.     if [catch {glob $f} file] {
  641.     Exmh_Status $file
  642.     return 0
  643.     }
  644.     if ![info exists mhProfile(aliasfile)] {
  645.     Exmh_Status "No AliasFile MH profile"
  646.     return 0
  647.     }
  648.     if [catch {exec egrep {^[     ]*alias} $file} new_aliases] {
  649.     Exmh_Status "No aliases in $file"
  650.     return 0
  651.     }
  652.     set out [open [Mh_Pathname $mhProfile(aliasfile)] {WRONLY CREAT APPEND}]
  653.     foreach a [split $new_aliases \n] {
  654.     if [regexp {^alias ([^     ]+)[     ](.*)$} $a match key value] {
  655.         regsub -all { +} $value {, } value
  656.         if ![info exists aliases($key)] {
  657.         puts $out "$key: $value"
  658.         }
  659.     } else {
  660.         Exmh_Status "Cannot regexp $a"
  661.     }
  662.     }
  663.     close $out
  664.     return 1
  665. }
  666.  
  667.  
  668.